from django.db.models import Q
from django.http import JsonResponse
from django.views import View
from app.models import *
from django.core.cache import cache
from app.RoleMethod.PublicMethod import PublicMethod
import json

publicMethod = PublicMethod()


# 添加关卡
class AddLevel(View):
    """
    模块: 添加关卡
    接口信息:
        POST:
            type: 关卡类型
            token： token认证
            title： 关卡标题
            description： 关卡描述
            nick: 昵称
            status：关卡隐藏
    返回信息:
        POST:
            status: 数据请求状态
            message: 提示信息
    """
    def post(self, request):
        type = request.POST.get('type', -1)
        token = request.COOKIES.get('token')
        title = request.POST.get('title', '')
        description = request.POST.get('description', '')
        user_id = cache.get(token)
        nick = publicMethod.get_user_nick(token)
        user_power = User.objects.filter(user_id=user_id).first().user_power
        defunct = request.POST.get('defunct')
        if defunct == 'true':
            defunct = True
        elif defunct == 'false':
            defunct = False
        if not token:
            return JsonResponse({'status': False, 'message': '你需要登录才能进行添加'})
        if user_power != 0 and user_power != 1:
            return JsonResponse({'status': False, 'message': '你没有添加权限'})
        if not type or type < '0':
            return JsonResponse({'status': False, 'message': '缺少类型参数'})
        if not title or title == '':
            return JsonResponse({'status': False, 'message': '缺少标题参数'})
        if type == '1':
            front_id = request.POST.get('front_id')
            num = Level.objects.filter(front_id=front_id).count() + 1
            problems = request.POST.get('problems', '')
            values = json.loads(problems)
            if not front_id or not problems or problems == '':
                return JsonResponse({'status': False, 'message': '缺少一些参数'})
            try:
                Level.objects.create(
                    title=title,
                    description=description,
                    type=1,
                    num=num,
                    front_id=front_id,
                    creator=user_id,
                    nick=nick,
                    defunct=defunct,
                    isdelete=False,
                )
                level_id = Level.objects.filter(front_id=front_id, num=num).values('level_id').order_by('level_id').first()
                level_id = level_id['level_id']
                i = 1
                for problem in values:
                    LevelProblem.objects.create(
                        problem_id=problem,
                        level_id=level_id,
                        num=i
                    )
                    i += 1
                if i - 1 == len(values):
                    return JsonResponse({'status': True, 'message': '成功'})
                else:
                    return JsonResponse({'status': True, 'message': '某些题目未添加'})
            except:
                return JsonResponse({'status': False, 'message': '无法添加名为level的表的数据。你可能缺少一个参数'})
        # 关卡大类添加
        elif type == '2':
            num = Level.objects.filter(type=2).count() + 1
            try:
                Level.objects.create(
                    title=title,
                    description=description,
                    type=2,
                    num=num,
                    front_id=0,
                    creator=user_id,
                    nick=nick,
                    defunct=defunct,
                    isdelete=False,
                )
                return JsonResponse({'status': True, 'message': '创建成功'})
            except:
                return JsonResponse({'status': False, 'message': '无法添加名为level的表的数据。你可能缺少一个参数'})
        else:
            return JsonResponse({'status': False, 'message': '请输入正确的类型'})

class EditLevel(View):
    """
    模块: 编辑关卡
    接口信息:
        POST:
            level_id: 关卡ID
            type: 关卡类型
            token： token认证
            title： 关卡标题
            description： 关卡描述
            front_id： 属于哪个大类
            problems: 关卡题目
    返回信息:
        POST:
            status: 数据请求状态
            message: 提示信息
    """
    def post(self, request):
        level_id = request.POST.get('level_id')
        type = request.POST.get('type', -1)
        token = request.COOKIES.get('token')
        user_id = cache.get(token)
        user_power = User.objects.filter(user_id=user_id).first().user_power
        thisLevel = Level.objects.filter(level_id=level_id, type=type)
        if not thisLevel:
            return JsonResponse({'status': False, 'message': '此关卡不存在'})
        if user_power != 0 and user_power != 1:
            return JsonResponse({'status': False, 'message': '你没有添加权限'})
        if not token:
            return JsonResponse({'status': False, 'message': '你需要登录才能进行编辑'})
        if type == '1':
            title = request.POST.get('title')
            description = request.POST.get('description', '')
            front_id = request.POST.get('front_id')
            problems = request.POST.get('problems', '')
            values = json.loads(problems)
            if not title or not front_id or not problems or problems == '':
                return JsonResponse({'status': False, 'message': '缺少一些参数'})
            LevelProblem.objects.filter(level_id=level_id).delete()
            i = 1
            message = {}
            for problem in values:
                LevelProblem.objects.create(
                    level_id=level_id,
                    problem_id=int(problem),
                    num=i
                )
                i += 1
            if i - 1 == len(values):
                message['editproblem'] = 'success'
            Level.objects.filter(level_id=level_id).update(
                title=title,
                description=description,
                front_id=front_id,
            )
            message['message'] = '成功'
            message['status'] = True
            return JsonResponse(message, safe=False)
        elif type == '2':
            title = request.POST.get('title', '')
            description = request.POST.get('description', '')
            try:
                Level.objects.filter(level_id=level_id).update(
                    title=title,
                    description=description,
                )
                return JsonResponse({'status': True, 'message': '修改成功'})
            except:
                return JsonResponse({'status': False, 'message': '数据库连接失败'})
        else:
            return JsonResponse({'status': False, 'message': '类型错误'})


class DeleteLevel(View):
    """
    模块: 删除关卡
    接口信息:
        POST:
            level_id: 关卡ID
            token： token认证
    返回信息:
        POST:
            status: 数据请求状态
            message: 提示信息
       """
    def get(self, request):
        pass

    def post(self, request):
        level_id = request.POST.get('level_id')
        token = request.COOKIES.get('token')
        user_id = cache.get(token)
        user_power = User.objects.filter(user_id=user_id).first().user_power
        level_type = Level.objects.filter(level_id=level_id).first().type
        thislevel = Level.objects.filter(level_id=level_id).first()
        if not token:
            return JsonResponse({'status': False, 'message': '你需要登录才能进行删除'})
        if not level_id:
            return JsonResponse({'status': False, 'message': '此关卡不存在'})
        if user_power != 0 and user_power != 1:
            return JsonResponse({'status': False, 'message': '你没有操作权限'})
        try:
            if level_type == 1:
                problems = LevelProblem.objects.filter(level_id=level_id)
                for problem in problems:
                    problem.delete()
                thislevel.delete()
                return JsonResponse({'status': True, 'message': '删除成功'})
            else:
                levels = Level.objects.filter(level_pre=level_id)
                for level in levels:
                    problems = LevelProblem.objects.filter(level_id=level.level_id)
                    for problem in problems:
                        problem.delete()
                    level.delete()
                thislevel.delete()
            return JsonResponse({'status': True, 'message': '删除成功'})
        except:
            return JsonResponse({'status': False, 'message': '数据库连接失败'})

class EditHideLevel(View):
    """
    模块: 编辑关卡隐藏
    接口信息:
        POST:
            level_id: 关卡ID
            token：token认证
            defunct: 显示状态
    返回信息:
        POST:
            status: 数据请求状态
            message: 提示信息
    """
    def get(self, request):
        pass

    def post(self, requet):
        token = requet.COOKIES.get('token')
        level_id = requet.POST.get('level_id')
        print(level_id)
        defunct = requet.POST.get('defunct')
        print(defunct)
        user_id = cache.get(token)
        user_power = User.objects.filter(user_id=user_id).first().user_power
        if not token:
            return JsonResponse({'status': False, 'message': '你需要登录才能进行修改操作'})
        if user_power != 0 and user_power != 1:
            return JsonResponse({'status': False, 'message': '你没有修改权限'})
        try:
            if defunct == 'false':
                defunct = False
            else:
                defunct = True
            print(defunct)
            Level.objects.filter(level_id=level_id).update(
                defunct=defunct
            )
            return JsonResponse({'status': True, 'message': '成功'})
        except:
            return JsonResponse({'status': False, 'message': '数据库连接失败'})


class GetLevelList(View):
    """
    模块: 获取关卡列表
    接口信息:
        GET:
            token: token认证
            user_id: 用户ID
    返回信息:
        GET:
            status: 数据请求状态
            message: 提示信息
    """
    def get(self, request):
        token = request.COOKIES.get('token')
        user_id = cache.get(token)
        levels_list = []
        big_levels = Level.objects.filter(type=2).order_by('num')
        small_level = Level.objects.filter(type=1)
        for big_level in big_levels:
            level_pass = 0
            level_list = []
            levels = small_level.filter(front_id=big_level.level_id).order_by('num')
            level_numbers = levels.count()
            for level in levels:
                problem_numbers = LevelProblem.objects.filter(level_id=level.level_id).count()
                pass_numbers = LevelPass.objects.filter(level_id=level.level_id).count()
                is_pass = False
                if user_id:
                    level_pass_list = LevelPass.objects.filter(user_id=user_id, level_id=level.level_id)
                    if level_pass_list.exists():
                        is_pass = True
                        level_pass = level_pass + 1
                level_list.append({
                    'level_id': level.level_id,
                    'title': level.title,
                    'description': level.description,
                    'num': level.num,
                    'status': level.defunct,
                    'creator': level.creator,
                    'front_id': level.front_id,
                    'level_pass': is_pass,
                    'pass_numbers': pass_numbers,
                    'problem_numbers': problem_numbers,
                    'type': level.type,
                })
            levels_list.append({
                'level_id': big_level.level_id,
                'title': big_level.title,
                'description': big_level.description,
                'status': big_level.defunct,
                'front_id': big_level.front_id,
                'creator': big_level.creator,
                'level_list': level_list,
                'level_pass': level_pass,
                'level_numbers': level_numbers,
                'type': big_level.type,
            })
        return JsonResponse({'status': True, 'message': levels_list})

    def post(self, request):
        pass

class GetProblem(View):
    """
    模块: 获取题目列表
    接口信息:
        GET:
            level_id: token认证
            user_id: 用户ID
    返回信息:
        GET:
            status: 数据请求状态
            message: 提示信息
    """
    def get(self, request):
        level_id = request.GET.get('level_id')
        token = request.COOKIES.get('token')
        user_id = cache.get(token)
        problem_list = []
        problems = LevelProblem.objects.filter(level_id=level_id)
        for problem in problems:
            question = Problem.objects.filter(problem_id=problem.problem_id).first()
            if question:
                problem_title = question.problem_title
            else:
                continue
            problem_status = 0
            if user_id:
                solutions = Solution.objects.filter(problem_id=problem.problem_id, user_id=user_id).values('run_result')
                if solutions.exists():
                    if 4 in solutions:
                        problem_status = 1
                    else:
                        problem_status = -1
            problem_list.append({
                'problem_id': problem.problem_id,
                'problem_status': problem_status,
                'problem_title': problem_title,
                'memory_limit': question.memory_limit,
                'problem_description': question.problem_description,
                'time_limit': question.time_limit,
            })
        return JsonResponse({'status': True, 'message': problem_list})

class LevelCompletion(View):
    """
    模块: 关卡完成
    接口信息:
        POST:
            token: token认证
            level_id: 关卡ID
    返回信息:
        POST:
            status: 数据请求状态
            message: 提示信息
    """
    def get(self, request):
        pass

    def post(self, request):
        level_id = request.POST.get('level_id')
        token = request.COOKIES.get('token')
        user_id = cache.get(token)
        if not user_id:
            return JsonResponse({'status': False, 'message': '你需要登录才能进行修改操作'})
        level_problems = LevelProblem.objects.filter(level_id=level_id).order_by('num')
        numbers_pass = 0
        number = level_problems.count()
        passes = LevelPass.objects.filter(level_id=level_id, user_id=user_id)
        if passes:
            return JsonResponse({'status': False, 'message': '已通关，请勿重复点击'})
        for level_problem in level_problems:
            passes = Solution.objects.filter(problem_id=level_problem.problem_id, user_id=user_id, run_result=4)
            if passes:
                numbers_pass += 1
        if numbers_pass == number:
            LevelPass.objects.create(
                level_id=level_id,
                user_id=user_id
            )
            return JsonResponse({'status': True, 'message': '通关'})
        else:
            return JsonResponse({'status': False, 'message': '未通关'})

class LevelMove(View):
    """
    模块: 关卡移动
    接口信息:
        POST:
            token: token认证
            level_id: 关卡ID
            type: 关卡类型
            move: 关卡移动
            front_id: 属于哪个大关卡
    返回信息:
        POST:
            status: 数据请求状态
            message: 提示信息
    """
    def get(self, request):
        pass

    def post(self, request):
        level_id = request.POST.get('level_id')
        token = request.COOKIES.get('token')
        user_id = cache.get(token)
        user_power = User.objects.filter(user_id=user_id).first().user_power
        type = request.POST.get('type')
        move = request.POST.get('move')
        front_id = request.POST.get('front_id')
        if not user_id:
            return JsonResponse({'status': False, 'message': '用户未登录'})
        if user_power != 0 and user_power != 1:
            return JsonResponse({'status': False, 'message': '你没有操作权限'})
        if not level_id:
            return JsonResponse({'status': False, 'message': '此关卡不存在'})
        if not type:
            return JsonResponse({'status': False, 'message': '类型错误'})
        if not move:
            return JsonResponse({'status': False, 'message': '移动信息错误'})
        if type == '1':
            this_level = Level.objects.filter(level_id=level_id).first()
            num = this_level.num
            next_level = Level.objects.filter(front_id=front_id, num=num + 1).first()
            last_level = Level.objects.filter(front_id=front_id, num=num - 1).first()
            if move == '2':
                if not next_level:
                    return JsonResponse({'status': False, 'message': '已到底了，无法继续下移'})
                else:
                    this_level.num = this_level.num+1
                    this_level.save()
                    next_level.num = next_level.num-1
                    next_level.save()
                    return JsonResponse({'status': True, 'message': '成功'})
            elif move == '1':
                if not last_level:
                    return JsonResponse({'status': False, 'message': '已到顶了，无法继续上移'})
                else:
                    this_level.num = this_level.num-1
                    this_level.save()
                    last_level.num = last_level.num+1
                    last_level.save()
                    return JsonResponse({'status': True, 'message': '成功'})
        elif type == '2':
            this_level = Level.objects.filter(level_id=level_id).first()
            num = this_level.num
            next_level = Level.objects.filter(front_id=front_id, num=num+1).first()
            last_level = Level.objects.filter(front_id=front_id, num=num-1).first()
            if move == '2':
                if not next_level:
                    return JsonResponse({'status': False, 'message': '已到底了，无法继续下移'})
                else:
                    this_level.num = this_level.num + 1
                    print(this_level.num)
                    this_level.save()
                    next_level.num = next_level.num - 1
                    next_level.save()
                    return JsonResponse({'status': True, 'message': '成功'})
            elif move == '1':
                if not last_level:
                    return JsonResponse({'status': False, 'message': '已到顶了，无法继续上移'})
                else:
                    this_level.num = this_level.num - 1
                    this_level.save()
                    last_level.num = last_level.num + 1
                    last_level.save()
                    return JsonResponse({'status': True, 'message': '成功'})
        else:
            return JsonResponse({'status': False, 'message': '数据连接失败'})

class SmallLevelMove(View):
    """
    模块: 改变小关卡所属
    接口信息:
        GET:
            NONE
    返回信息:
        GET:
            status: 数据请求状态
            message: 提示信息
    """
    def get(self, request):
        big_level = []
        levels = Level.objects.filter(type='2')
        for level in levels:
            big_level.append({
                'level_id': level.level_id,
                'title': level.title
            })
        return JsonResponse({'status': True, 'message': big_level})

    def post(self, request):
        pass

class SearchProblem(View):
    """
    模块: 关卡题目搜索
    接口信息:
        GET:
            level_id: 关卡ID
            text：搜索文本
    返回信息:
        GET:
            status: 数据请求状态
            message: 提示信息
    """
    def get(self, request):
        problem_list = []
        problems = Problem.objects.all()
        for problem in problems:
            problem_list.append({
                'problem_id': problem.problem_id,
                'problem_title': problem.problem_title
            })
        return JsonResponse({'status': True, 'message': problem_list})

    def post(self, request):
        pass

class SearchLevel(View):
    """
    模块: 大关卡搜索
    接口信息:
        GET:
            text：搜索文本
    返回信息:
        GET:
            status: 数据请求状态
            message: 提示信息
    """
    def get(self, request):
        text = request.GET.get('text')
        levels_list = []
        levels = Level.objects.filter(type=2)
        if text:
            big_levels = levels.filter(Q(title__contains=text) | Q(description__contains=text) | Q(creator__contains=text))
            for big_level in big_levels:
                level_list = []
                levels = Level.objects.filter(front_id=big_level.level_id)
                for level in levels:
                    problem_list = []
                    problems = LevelProblem.objects.filter(level_id=level.level_id)
                    for problem in problems:
                        question = Problem.objects.filter(problem_id=problem.problem_id).first()
                        if question:
                            problem_title = question.problem_title
                        else:
                            continue
                        problem_list.append({
                            'problem_id': problem.problem_id,
                            'level_id': problem.level_id,
                            'num': problem.num,
                            'problem_title': problem_title,
                            'problem_description': question.problem_description,
                            'time_limit': question.time_limit,
                            'memory_limit': question.memory_limit,
                        })
                    if level.defunct == '1':
                        status = True
                    else:
                        status = False
                    level_list.append({
                        'level_id': level.level_id,
                        'title': level.title,
                        'description': level.description,
                        'level_pre': level.level_pre,
                        'pass_num': level.pass_num,
                        'type': level.type,
                        'num': level.num,
                        'front_id': level.front_id,
                        'creator': level.creator,
                        'nick': level.nick,
                        'status': status,
                        'problem_list': problem_list,
                    })
                if big_level.defunct == '0':
                    status = False
                else:
                    status = True
                levels_list.append({
                    'level_id': big_level.level_id,
                    'title': big_level.title,
                    'description': big_level.description,
                    'level_pre': big_level.level_pre,
                    'pass_num': big_level.pass_num,
                    'type': big_level.type,
                    'num': big_level.num,
                    'front_id': big_level.front_id,
                    'creator': big_level.creator,
                    'nick': big_level.nick,
                    'status': status,
                    'level_list': level_list,
                })
        else:
            big_levels = Level.objects.filter(type=2).order_by('num')
            small_level = Level.objects.filter(type=1)
            for big_level in big_levels:
                level_list = []
                levels = small_level.filter(front_id=big_level.level_id).order_by('num')
                for level in levels:
                    problem_list = []
                    problems = LevelProblem.objects.filter(level_id=level.level_id)
                    for problem in problems:
                        question = Problem.objects.filter(problem_id=problem.problem_id).first()
                        if question:
                            problem_title = question.problem_title
                        else:
                            continue
                        problem_list.append({
                            'problem_id': problem.problem_id,
                            'level_id': problem.level_id,
                            'num': problem.num,
                            'problem_title': problem_title,
                            'problem_description': question.problem_description,
                            'time_limit': question.time_limit,
                            'memory_limit': question.memory_limit,
                        })
                    pass_numbers = LevelPass.objects.filter(level_id=level.level_id).count()
                    if level.defunct == '1':
                        status = True
                    else:
                        status = False
                    level_list.append({
                        'level_id': level.level_id,
                        'title': level.title,
                        'description': level.description,
                        'level_pre': level.level_pre,
                        'pass_num': level.pass_num,
                        'type': level.type,
                        'num': level.num,
                        'front_id': level.front_id,
                        'creator': level.creator,
                        'nick': level.nick,
                        'status': status,
                        'problem_list': problem_list,
                        'pass_numbers': pass_numbers,
                    })
                if big_level.defunct == '0':
                    status = False
                else:
                    status = True
                levels_list.append({
                    'level_id': big_level.level_id,
                    'title': big_level.title,
                    'description': big_level.description,
                    'level_pre': big_level.level_pre,
                    'pass_num': big_level.pass_num,
                    'type': big_level.type,
                    'num': big_level.num,
                    'front_id': big_level.front_id,
                    'creator': big_level.creator,
                    'nick': big_level.nick,
                    'status': status,
                    'level_list': level_list,
                })
        if levels_list:
            return JsonResponse({'status': True, 'message': levels_list})
        else:
            return JsonResponse({'status': False, 'message': '无记录'})

    def post(self, request):
        pass

